rem moving platform waypoint array (number of platforms, number of way points)
dim platform_wp_x(8,5)
dim platform_wp_y(8,5)
dim platform_wp_z(8,5)
rem camera variables
global camx#
global camy#
global camz#
rem clickdelay variable
global clickdelay
rem enemy quantity varaiable
global enemy_qty
global live_enemies
rem level name variable
global level_number
global level_qty
level_qty=12
global level_start_time
global level_timer
global hurry_up
global death_active
global end_level
global level_offset
rem load sounds
load 3dsound "media\sounds\pop.wav",1
load sound "media\sounds\jump.wav",2
load sound "media\sounds\baddie_kill.wav",3
load sound "media\sounds\bubble_shoot.wav",4
load sound "media\sounds\bub_die.wav",5
load sound "media\sounds\hurry.wav",6
load sound "media\sounds\bonus.wav",7
load sound "media\sounds\big_bonus.wav",8
load 3dsound "media\sounds\death.wav",9
rem load music
load music "media\music\Bubble Bobble New Age Theme.mp3",1
rem load player texture
load image "media\characters\bub.bmp",1
rem load bubble texture
load image "media\effects\bubble.bmp",5
rem load enemy textures
load image "media\characters\baddie_1.bmp",100
load image "media\characters\baddie_1a.bmp",101
load image "media\characters\baddie_2.bmp",102
load image "media\characters\baddie_2a.bmp",103
load image "media\characters\baddie_3.bmp",104
load image "media\characters\baddie_3a.bmp",105
load image "media\characters\baddie_4.bmp",106
load image "media\characters\baddie_4a.bmp",107
rem load other textures
load image "media\effects\cloud.bmp",986
load image "media\effects\fire.bmp",987
rem setup player object
load object "media\characters\bub.x",1
texture object 1,1
hide object 1
set object speed 1,100
make object collision box 1,0-(player.size_x/2),0-(player.size_y/2),0-(player.size_z/2),player.size_x/2,player.size_y/2,player.size_z/2,0
rem setup player bubble objects
for a=10 to max_bubbles+10
make object sphere a,10,16,16
texture object a,5
ghost object on a
hide object a
make object collision box a,-27,-27,-27,27,27,27,0
next a
rem setup death ghost object
load object "media\characters\death.x",5
hide object 5
rem menu setup
global menu
menu=1
level_number=rnd(level_qty-1)+1
gosub new_level
rem scoreboard setup
global line$
global high_score
rem scoreboard arrays
dim scoreboard_name$(9)
dim scoreboard_score(9)
rem set default scoreboard names and scores
scoreboard_name$(0)="Tom"
scoreboard_score(0)=100000
scoreboard_name$(1)="Azazel"
scoreboard_score(1)=75000
scoreboard_name$(2)="Cro"
scoreboard_score(2)=50000
scoreboard_name$(3)="Maz"
scoreboard_score(3)=25000
scoreboard_name$(4)="Karl"
scoreboard_score(4)=20000
scoreboard_name$(5)="Rory"
scoreboard_score(5)=15000
scoreboard_name$(6)="Amy"
scoreboard_score(6)=10000
scoreboard_name$(7)="Bub"
scoreboard_score(7)=5000
scoreboard_name$(8)="Bob"
scoreboard_score(8)=1000
scoreboard_name$(9)="pepe"
scoreboard_score(9)=500
remstart load scores from file
if file exist("scores.dat")>0
open to read 1,"scores.dat"
for a=0 to 9
read string 1,scoreboard_name$(a)
read file 1,scoreboard_score(a)
next a
close file 1
endif
remend
rem set sync rate
sync rate 60
sync on
play sound 8
rem main game loop
do
rem game over
if game_over>0
center text screen width()/2,screen height()/2,"Game Over"
if timer()-game_over>3000
game_over=0
menu=1
rem set camera to follow an enemy for menu
if enemy(enemy_cam).life<1
for a=0 to enemy_qty-1
if enemy(a).life>0
enemy_cam=a
exit
endif
next a
endif
rem check if players score is a high score
for a=0 to 9
if player.score>scoreboard_score(a)
high_score=a+1
menu=0
clear entry buffer
exit
endif
next a
endif
endif
if menu>0 then gosub menu
if high_score>0 then gosub high_score_entry
if player.score>=player.extra_life and player.life>-1
player.life=player.life+1
player.extra_life=player.extra_life+100000
play sound 8
endif
if hurry_up<1
rem moving platforms control
if moving_platform_qty>0
object_num=2000
for a=0 to moving_platform_qty-1
moving_platform(a).old_pos_x=object position x(object_num)
moving_platform(a).old_pos_z=object position z(object_num)
point object object_num+2,platform_wp_x(a,moving_platform(a).next_waypoint),platform_wp_y(a,moving_platform(a).next_waypoint),platform_wp_z(a,moving_platform(a).next_waypoint)
move object object_num+2,1
position object object_num,object position x(object_num+2),object position y(object_num+2),object position z(object_num+2)
position object object_num+1,object position x(object_num+2),object position y(object_num+2)+10.5,object position z(object_num+2)
player.pos_x=newxvalue(player.pos_x,atanfull(object position x(object_num)-moving_platform(a).old_pos_x,object position z(object_num)-moving_platform(a).old_pos_z),abs(object position x(object_num)-moving_platform(a).old_pos_x))
player.pos_z=newzvalue(player.pos_z,atanfull(object position x(object_num)-moving_platform(a).old_pos_x,object position z(object_num)-moving_platform(a).old_pos_z),abs(object position z(object_num)-moving_platform(a).old_pos_z))
endif
if get object collision y()>0
player.jump=0
player.gravity=-0.1
endif
endif
inc object_num,3
next a
rem reposition player after dropping into warp tunnel
if player.pos_y<-500
player.pos_x=level_offset
player.pos_y=3000
player.pos_z=0
player.jump_angle=0
endif
rem player animation control
if player.animate=1
loop object 1,5,25
player.animate=2
endif
if player.animate>1 and keystate(17)<1 and keystate(30)<1 and keystate(31)<1 and keystate(32)<1
player.animate=0
play object 1,1,1
endif
rem player fire animation
if player.fire_animation>0
if player.fire_animation<50
rotate limb 1,3,0,0,limb angle z(1,3)-5
player.fire_animation=player.fire_animation+5
endif
if player.fire_animation>50
rotate limb 1,3,0,0,limb angle z(1,3)+5
player.fire_animation=player.fire_animation+5
endif
if player.fire_animation>95
player.fire_animation=0
rotate limb 1,3,0,0,0
endif
endif
rem player death animation
if player.death_animation>0
player.ang_y=player.ang_y+10
player.death_animation=player.death_animation+1
rem end of death animation
if player.death_animation>100
player.death_animation=0
rem if player has lives left make invincible else gameover
if player.life>-1
player.invincible=2
player.invincible_timer=timer()
ghost object on 1
else
game_over=timer()
rem hide player object
hide object 1
endif
endif
endif
rem flash player if invincible
if player.invincible>1
if player.invincible=2 then ghost object on 1
if player.invincible=6 then ghost object off 1
player.invincible=player.invincible+1
if player.invincible>8 then player.invincible=2
if timer()-player.invincible_timer>5000
player.invincible=0
ghost object off 1
endif
endif
if menu<1
rem update player object positions and orientation
position object 1,player.pos_x,player.pos_y,player.pos_z
rotate object 1,0,player.ang_y,0
rem position listener
position listener player.pos_x,player.pos_y,player.pos_z
rotate listener 0,player.ang_y,0
rem player camera
if player.death_animation<1
camx#=curvevalue(newxvalue(object position x(1),player.ang_y,-60),camx#,8)
camy#=curvevalue(newyvalue(object position y(1)+50,player.ang_x,-60),camy#,5)
camz#=curvevalue(newzvalue(object position z(1),player.ang_y,-60),camz#,8)
position camera camx#,camy#,camz#
point camera newxvalue(object position x(1),player.ang_y,60),newyvalue(object position y(1),player.ang_x,60),newzvalue(object position z(1),player.ang_y,60)
else
point camera object position x(1),object position y(1),object position z(1)
endif
endif
rem death control
if death_active>0
point object 5,object position x(1),object position y(1),object position z(1)
move object 5,1.5
position sound 9,object position x(5),object position y(5),object position z(5)
if distance_3d(object position x(1),object position x(5),object position y(1),object position y(5),object position z(1),object position z(5))<20
player.death_animation=1
player.life=player.life-1
level_start_time=timer()
death_active=0
hide object 5
stop sound 9
play sound 5
endif
endif
rem enemy control loop
for a=0 to enemy_qty-1
if enemy(a).life>0
rem hold old enemy positions
enemy(a).old_pos_x=enemy(a).pos_x
enemy(a).old_pos_y=enemy(a).pos_y
enemy(a).old_pos_z=enemy(a).pos_z
rem fire rate control
if enemy(a).fire_rate>0 then enemy(a).fire_rate=enemy(a).fire_rate-1
if enemy(a).trapped<1
rem enemy ai control
if enemy(a).enemy_type=1 then basic_ai(a)
if enemy(a).enemy_type=2 then platform_patrol_ai(a)
if player_bubble(bubble_num).speed>3 and player_bubble(bubble_num).enemy_trapped<0
for a=0 to enemy_qty-1
rem trapping nearby enemy in bubble
if enemy(a).trapped<1 and enemy(a).life>0
if distance_3d(player_bubble(bubble_num).pos_x,enemy(a).pos_x,player_bubble(bubble_num).pos_y,enemy(a).pos_y,player_bubble(bubble_num).pos_z,enemy(a).pos_z)<32
enemy(a).trapped=1
player_bubble(bubble_num).enemy_trapped=a
player_bubble(bubble_num).scale=495
play object enemy(a).object_num,0,0
exit
endif
endif
next enemy
endif
rem bubble to player collision
if object collision(bubble_obj_num,1)>0
rem burst bubble if player jumps up into it
if player.gravity>0 and player_bubble(bubble_num).pos_y>player.pos_y
player.score=player.score+10
player_bubble(bubble_num).life=0
endif
rem jump if space is pressed and player drops on bubble or else burst
if player.gravity<0 and player_bubble(bubble_num).pos_y<player.pos_y
player.score=player.score+10
if spacekey()>0 and player.pos_y<950
player.jump=2.5
play sound 2
if keystate(17)>0
player.jump_angle=player.ang_y
else
player.jump_angle=0
endif
else
player_bubble(bubble_num).life=0
endif
endif
rem kill trapped badguy
if player_bubble(bubble_num).life=0 and player_bubble(bubble_num).enemy_trapped>-1
if get static collision hit(player_bubble(bubble_num).old_pos_x-27,player_bubble(bubble_num).old_pos_y-27,player_bubble(bubble_num).old_pos_z-27,player_bubble(bubble_num).old_pos_x+27,player_bubble(bubble_num).old_pos_y+27,player_bubble(bubble_num).old_pos_z+27,player_bubble(bubble_num).pos_x-27,player_bubble(bubble_num).pos_y-27,player_bubble(bubble_num).pos_z-27,player_bubble(bubble_num).pos_x+27,player_bubble(bubble_num).pos_y+27,player_bubble(bubble_num).pos_z+27)>0
if timer()-player_bubble(bubble_num).life>30000 then player_bubble(bubble_num).life=0
rem free any trapped baddies
if player_bubble(bubble_num).life<1
hide object bubble_obj_num
position sound 1,player_bubble(bubble_num).pos_x,player_bubble(bubble_num).pos_y,player_bubble(bubble_num).pos_z
play sound 1
if player_bubble(bubble_num).enemy_trapped>-1
rem change platform patrol ai to basic ai
if enemy(player_bubble(bubble_num).enemy_trapped).enemy_type=2 then enemy(player_bubble(bubble_num).enemy_trapped).enemy_type=1
if enemy(player_bubble(bubble_num).enemy_trapped).enemy_type=5 then enemy(player_bubble(bubble_num).enemy_trapped).enemy_type=4
rem loop animation on freed enemy
if enemy(player_bubble(bubble_num).enemy_trapped).enemy_type<3 or enemy(player_bubble(bubble_num).enemy_trapped).enemy_type=4 then loop object enemy(player_bubble(bubble_num).enemy_trapped).object_num,0,20
make object collision box enemy(a).object_num,0-(enemy(a).size_x/2),0-(enemy(a).size_y/2),0-(enemy(a).size_z/2),enemy(a).size_x/2,enemy(a).size_y/2,enemy(a).size_z/2,0
position object enemy(a).object_num,0+level_offset,1500,0
center text screen width()/2,screen height()/2,"Get Ready!"
sync
menu=0
player.score=0
player.extra_life=100000
player.life=3
level_number=1
gosub new_level
show object 1
loop music 1
set music speed 1,100
else
rem menu text
center text screen width()/2,40,"Bubble Bobble 3D"
rem display scoreboard
center text screen width()/2,100,"Top Scores"
y=140
for a=0 to 9
center text screen width()/2,y,str$(a+1)+") "+scoreboard_name$(a)+" - "+str$(scoreboard_score(a))
inc y,20
next a
center text screen width()/2,400,"Created in DarkBASIC Professional by Thomas Long"
center text screen width()/2,420,"Music by Wendell Norman"
rem camera follow enemy
camx#=curvevalue(newxvalue(object position x(enemy(enemy_cam).object_num),enemy(enemy_cam).ang_y,-60),camx#,8)
camy#=curvevalue(newyvalue(object position y(enemy(enemy_cam).object_num)+50,0,-60),camy#,5)
camz#=curvevalue(newzvalue(object position z(enemy(enemy_cam).object_num),enemy(enemy_cam).ang_y,-60),camz#,8)
position camera camx#,camy#,camz#
point camera newxvalue(object position x(enemy(enemy_cam).object_num),enemy(enemy_cam).ang_y,60),newyvalue(object position y(enemy(enemy_cam).object_num),0,60),newzvalue(object position z(enemy(enemy_cam).object_num),enemy(enemy_cam).ang_y,60)
endif
return
high_score_entry:
rem text entry
new$=entry$()
for n=1 to len(new$)
if asc(mid$(new$,n))=8
line$=left$(line$,len(line$)-1)
else
line$=line$+mid$(new$,n)
endif
next n
clear entry buffer
rem display text
center text screen width()/2,screen height()/2,"High score! Enter your name."
center text screen width()/2,screen height()/2+20,line$
rem add score to scoreboard
if returnkey()>0
for b=9 to high_score-1 step -1
scoreboard_name$(b)=scoreboard_name$(b-1)
scoreboard_score(b)=scoreboard_score(b-1)
next b
scoreboard_name$(high_score-1)=line$
scoreboard_score(high_score-1)=player.score
high_score=0
menu=1
remstart save scoreboard to file
if file exist("scores.dat") then delete file "scores.dat"